package com.molichuxing.gateway.bff.financial.services.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.molichuxing.framework.dto.Paged;
import com.molichuxing.framework.dto.TabDto;
import com.molichuxing.framework.utils.ObjectCastUtil;
import com.molichuxing.gateway.bff.dealer.services.impl.DealerBffServiceImpl;
import com.molichuxing.gateway.bff.financial.convertor.Convert;
import com.molichuxing.gateway.bff.financial.entity.response.ReceiptVo;
import com.molichuxing.gateway.bff.financial.services.StandingBookBffService;
import com.molichuxing.gateway.property.StandingBusinessTypeEnum;
import com.molichuxing.services.business.dto.response.LedgerRepaymentPeriodBizDto;
import com.molichuxing.services.business.dto.response.PaymentBizDto;
import com.molichuxing.services.business.dto.response.UserBizDto;
import com.molichuxing.services.business.service.OrderExclusivelBizService;
import com.molichuxing.services.business.service.OrderScheduleBizService;
import com.molichuxing.services.business.service.PaymentBizService;
import com.molichuxing.services.business.service.UserBizService;
import com.molichuxing.services.infrastructure.dto.response.DealerDto;
import com.molichuxing.services.infrastructure.dto.response.OrderExclusivelDto;
import com.molichuxing.services.infrastructure.dto.response.OrderMileageDto;
import com.molichuxing.services.infrastructure.dto.response.OrderSubscribeDto;
import com.molichuxing.services.infrastructure.dto.response.UserDto;
import com.molichuxing.services.infrastructure.service.DealerService;
import com.molichuxing.services.infrastructure.service.OrderDealerService;
import com.molichuxing.services.infrastructure.service.OrderExclusivelService;
import com.molichuxing.services.infrastructure.service.OrderMileageService;
import com.molichuxing.services.infrastructure.service.OrderSubscribeService;
import com.molichuxing.services.infrastructure.service.PaymentService;
import com.molichuxing.services.infrastructure.service.UserService;
import com.molichuxing.services.property.OrderExclusivelStatusEnum;
import com.molichuxing.services.property.OrderPaymentMethodEnum;
import com.molichuxing.services.property.OrderSubscribeStatusEnum;
import com.molichuxing.services.property.PaymentBusinessTypeEnum;
import com.molichuxing.services.property.PaymentCostTypeEnum;


/**
 * 台账相关bff
 *
 * @author zhaopenghui
 * @date 2019年8月30日
 */
@Service("standingBookBffService")
public class StandingBookBffServiceImpl implements StandingBookBffService {
    private static final Logger logger = LoggerFactory.getLogger(DealerBffServiceImpl.class);

    @Resource
    private DealerService dealerService;
    @Resource
    private PaymentBizService paymentBizService;
    @Resource
    private UserBizService userBizService;
    @Resource
    private UserService userService;
    @Resource
    OrderExclusivelBizService orderExclusivelBizService;
    @Resource
    OrderScheduleBizService orderScheduleBizService;
	@Resource
	OrderMileageService orderMileageService;
	@Resource
	private PaymentService paymentService;
	@Resource
	OrderExclusivelService orderExclusivelService;
	@Resource
	OrderSubscribeService orderSubscribeService;
	@Resource
	OrderDealerService orderDealerService;

    /**
	 * 收款台账
	 *
	 * @param params
	 * @param pageNum
	 * @param pageSize
	 * @return
	 * @throws Exception
	 */
    @Override
	public Paged<ReceiptVo> getReceiptPage(Map<String, Object> params, Integer pageNum, Integer pageSize)
			throws Exception {
		Paged<ReceiptVo> result = new Paged<>(new ArrayList<>(), 0, pageSize);
		// 转换用户信息
		if (!xlateUser(params)) {
			return result;
		}

		Paged<PaymentBizDto> paymentBizDtoPage = paymentBizService.getPaymentPage(params, pageNum, pageSize);
		// 判断是否查询为空
		if (paymentBizDtoPage == null) {
			return result;
		} else if (paymentBizDtoPage.isEmpty()) {
			return result.setTotal(paymentBizDtoPage.getTotal()).setTab(paymentBizDtoPage.getTab());
		}

		result.setTotal(paymentBizDtoPage.getTotal()).setTab(paymentBizDtoPage.getTab());

		// 用户id
		List<Integer> userIds = new ArrayList<>();
		List<LedgerRepaymentPeriodBizDto> ledgerRepaymentPeriodBizDtos = new ArrayList<>();

		for (PaymentBizDto paymentBizDto : paymentBizDtoPage.getList()) {
			ReceiptVo receiptVo = Convert.toReceiptVo(paymentBizDto);
			result.getList().add(receiptVo);
			userIds.add(paymentBizDto.getUserId());
			if (PaymentBusinessTypeEnum.SUBSCRIBE.equals(paymentBizDto.getBusinessType())) {
				// 订阅里程不用查付款周期
				continue;
			}
			ledgerRepaymentPeriodBizDtos
					.add(new LedgerRepaymentPeriodBizDto(paymentBizDto.getOrderCode(), paymentBizDto.getScheduleId()));
		}

		// 查询订单付款周期信息
		Map<LedgerRepaymentPeriodBizDto, String> repaymentPeriodMap = null;
		if (!ledgerRepaymentPeriodBizDtos.isEmpty()) {
			repaymentPeriodMap = orderExclusivelBizService.getRepaymentPeriod(ledgerRepaymentPeriodBizDtos);
		}
		// 查询用户信息
		Map<Integer, UserBizDto> userMap = userBizService.getUsers(userIds);

		for (ReceiptVo receiptVo : result.getList()) {
			Integer payType = receiptVo.getPayType();
			Long orderCode = receiptVo.getOrderCode();
			Integer businessType = receiptVo.getBusinessType();
			// 付款周期
			if (repaymentPeriodMap != null && !repaymentPeriodMap.isEmpty()) {
				if (StringUtils.isBlank(receiptVo.getRepaymentPeriod())) {
					receiptVo.setRepaymentPeriod(repaymentPeriodMap
							.get(new LedgerRepaymentPeriodBizDto(receiptVo.getOrderCode(), receiptVo.getScheduleId())));
				}
			}
			// 用户信息
			UserBizDto userBizDto = userMap == null ? null
					: userMap.isEmpty() ? null : userMap.get(receiptVo.getUserId());
			receiptVo.setUserName(userBizDto == null ? null : userBizDto.getName());
            receiptVo.setRealName(userBizDto == null ? null : userBizDto.getRealName());
            receiptVo.setPhone(userBizDto == null ? null : userBizDto.getPhone());
            receiptVo.setIdNumber(userBizDto == null ? null : userBizDto.getIdNumber());

			if (payType != null && PaymentCostTypeEnum.PURCHASE.getValue()==payType) {
				OrderMileageDto orderMileage = orderMileageService.getOrderMileage(orderCode);
				if(orderMileage!=null){
					Long masterOrderCode = orderMileage.getMasterOrderCode();
					receiptVo.setOrderCode(masterOrderCode);
				}
			}

			getOrderInfo(businessType,orderCode,receiptVo);
		}
		return getPageTab(result);
    }

	/**
	 * 获取tab数据
	 *
	 * @param result
	 * @return
	 * @throws Exception
	 */
	private Paged<ReceiptVo> getPageTab(Paged<ReceiptVo> result) throws Exception {
		Map<Integer, Integer> statusCountMap = paymentService.getPaymentCountByBusinessType();
		List<TabDto> tabList = new ArrayList<>();
		for (StandingBusinessTypeEnum standingBusinessTypeEnum : StandingBusinessTypeEnum.values()) {
			int value = standingBusinessTypeEnum.getValue();
			String name = standingBusinessTypeEnum.getName();
			Integer count = 0;
		    if (null != statusCountMap && statusCountMap.size() > 0) {
				count = statusCountMap.get(value);
			}

			if (null == count) {
				count = 0;
			}

			TabDto tabDto = new TabDto();
			tabDto.setName(name);
			tabDto.setType(value);
			tabDto.setCount(count);
			tabList.add(tabDto);
		}

		return result.setTab(tabList);
	}


	/**
	 * 获取订单信息
	 *
	 * @param businessType
	 * @param orderCode
	 * @param receiptVo
	 * @throws Exception
	 */
	private void getOrderInfo(Integer businessType, Long orderCode, ReceiptVo receiptVo) throws Exception {
		if (PaymentBusinessTypeEnum.EXCLUSIVEL.getValue() == businessType) {
			OrderExclusivelDto orderExclusivelDto = orderExclusivelService.getOrderExclusivel(orderCode);
            if(null == orderExclusivelDto){
                return;
            }
			OrderPaymentMethodEnum paymentMethod = orderExclusivelDto.getPaymentMethod();
			OrderExclusivelStatusEnum orderStatus = orderExclusivelDto.getOrderStatus();
			if (paymentMethod != null) {
				receiptVo.setPaymentMethod(paymentMethod.getValue());
			}
			if (orderStatus != null) {
				receiptVo.setOrderStatus(orderStatus.getValue());
			}
		} else if (PaymentBusinessTypeEnum.SUBSCRIBE.getValue() == businessType) {
			OrderSubscribeDto orderSubscribe = orderSubscribeService.getOrderSubscribe(orderCode);
			if(null == orderSubscribe){
			    return;
            }
			OrderSubscribeStatusEnum orderStatus = orderSubscribe.getOrderStatus();
			if (orderStatus != null) {
				receiptVo.setOrderStatus(orderStatus.getValue());
			}
		}
	}
    /**
	 * 经销商台账
	 *
	 * @param params
	 * @param pageNum
	 * @param pageSize
	 * @return
	 * @throws Exception
	 */
    @Override
	public Paged<ReceiptVo> getDealerReceiptPage(Map<String, Object> params, Integer pageNum, Integer pageSize)
			throws Exception {
		Paged<ReceiptVo> result = new Paged<>(new ArrayList<>(), 0, pageSize);

		params.put("businessType", PaymentBusinessTypeEnum.DEALER.getValue());
		Object dealerId = params.get("dealerId");
		if (dealerId != null) {
			params.put("userId", dealerId);
			params.remove("dealerId");
		}

		Paged<PaymentBizDto> paymentBizDtoPage = paymentBizService.getPaymentPage(params, pageNum, pageSize);
		// 判断是否查询为空
		if (paymentBizDtoPage == null) {
			return result;
		} else if (paymentBizDtoPage.isEmpty()) {
			return result.setTotal(paymentBizDtoPage.getTotal()).setTab(paymentBizDtoPage.getTab());
		}

		result.setTotal(paymentBizDtoPage.getTotal()).setTab(paymentBizDtoPage.getTab());

		// 经销商id
		List<Integer> dealerIds = new ArrayList<>();
		List<LedgerRepaymentPeriodBizDto> ledgerRepaymentPeriodBizDtos = new ArrayList<>();

		for (PaymentBizDto paymentBizDto : paymentBizDtoPage.getList()) {
			ReceiptVo receiptVo = Convert.toReceiptVo(paymentBizDto);
			result.getList().add(receiptVo);
			dealerIds.add(paymentBizDto.getUserId());
			ledgerRepaymentPeriodBizDtos
					.add(new LedgerRepaymentPeriodBizDto(paymentBizDto.getOrderCode(), paymentBizDto.getScheduleId()));
		}

		// 查询订单付款周期信息
		Map<LedgerRepaymentPeriodBizDto, String> repaymentPeriodMap = orderScheduleBizService
				.getDealerRepaymentPeriod(ledgerRepaymentPeriodBizDtos);
		// 查询经销商信息
		Map<Integer, DealerDto> dealerMap = dealerService.getDealerMapByIds(dealerIds);

		for (ReceiptVo receiptVo : result.getList()) {
			Long orderCode = receiptVo.getOrderCode();
			// 付款周期
			receiptVo.setRepaymentPeriod(repaymentPeriodMap == null ? null
					: repaymentPeriodMap.isEmpty() ? null
							: repaymentPeriodMap.get(new LedgerRepaymentPeriodBizDto(receiptVo.getOrderCode(),
									receiptVo.getScheduleId())));
			// 经销商信息
			DealerDto dealerDto = dealerMap == null ? null
					: dealerMap.isEmpty() ? null : dealerMap.get(receiptVo.getUserId());
			receiptVo.setDealerId(dealerDto.getDealerId());
			receiptVo.setDealerShortName(dealerDto.getShortName());

			Integer orderDealerStatus = orderDealerService.getOrderDealerStatus(orderCode);
			receiptVo.setOrderStatus(orderDealerStatus);
		}

		return result;
    }


    /**
	 * 保证金台账
	 *
	 * @param params
	 * @param pageNum
	 * @param pageSize
	 * @return
	 * @throws Exception
	 */
    @Override
	public Paged<ReceiptVo> getDepositPage(Map<String, Object> params, Integer pageNum, Integer pageSize)
			throws Exception {
		Paged<ReceiptVo> result = new Paged<>(new ArrayList<>(), 0, pageSize);
		// 转换用户信息
		if (!xlateUser(params)) {
			return result;
		}

		Paged<PaymentBizDto> paymentBizDtoPage = paymentBizService.getDepositPage(params, pageNum, pageSize);

		// 判断是否查询为空
		if (paymentBizDtoPage == null) {
			return result;
		} else if (paymentBizDtoPage.isEmpty()) {
			return result.setTotal(paymentBizDtoPage.getTotal()).setTab(paymentBizDtoPage.getTab());
		}

		result.setTotal(paymentBizDtoPage.getTotal()).setTab(paymentBizDtoPage.getTab());

		// 用户id
		List<Integer> userIds = new ArrayList<>();
		for (PaymentBizDto paymentBizDto : paymentBizDtoPage.getList()) {
			ReceiptVo receiptVo = Convert.toReceiptVo(paymentBizDto);
			result.getList().add(receiptVo);
			userIds.add(paymentBizDto.getUserId());
		}

		// 查询用户信息
		Map<Integer, UserBizDto> userMap = userBizService.getUsers(userIds);

		for (ReceiptVo receiptVo : result.getList()) {
			Integer businessType = receiptVo.getBusinessType();
			Long orderCode = receiptVo.getOrderCode();

			// 用户信息
			UserBizDto userBizDto = userMap == null ? null
					: userMap.isEmpty() ? null : userMap.get(receiptVo.getUserId());
			receiptVo.setUserName(userBizDto == null ? null : userBizDto.getName());
			receiptVo.setRealName(userBizDto == null ? null : userBizDto.getRealName());
			receiptVo.setPhone(userBizDto == null ? null : userBizDto.getPhone());
			receiptVo.setIdNumber(userBizDto == null ? null : userBizDto.getIdNumber());

			getOrderInfo(businessType,orderCode,receiptVo);
		}

		return result;
    }

	/**
	 * 转换用户信息
	 * 
	 * @param params
	 */
	private boolean xlateUser(Map<String, Object> params) {
		String userName = ObjectCastUtil.castString(params.get("userName"));
		// 判断查询条件是否有用户信息
		if (StringUtils.isNotBlank(userName)) {
			// 查询用信息
			UserDto UserDto = userService.getUserByName(userName);
			if (UserDto == null) {
				// 用户不存在
				return false;
			}
			Integer userId = UserDto.getId();
			params.put("userId", userId);
			params.remove("userName");
			logger.info("[xlateUser]分页获取收款台账信息userId：" + userId);
		}
		return true;
	}
}
